<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>JavaScript Benchmark</title>
    <link rel="stylesheet" href="benchmark_style.css" type="text/css" />
    <script type="text/javascript" src="benchmark.js"></script>
    <link rel="stylesheet" href="tree.css" type="text/css" />
    <script type="text/javascript" src="prototype.js"></script>
    <script type="text/javascript" src="neodom.js"></script>
    <link type="text/css" rel="stylesheet" href="highlight.css" />
    <script type="text/javascript" src="highlight.js"></script>
    <script type="text/javascript" src="lang_js.js"></script>
  </head>
  <body>
    <h1>
      <a href="benchmark.js" name="top">Benchmark</a>
      <em>JavaScript benchmarking</em>
    </h1>
    <ul class="toc tree" id="toc">
      <li><a href="#version">Version</a></li>
      <li><a href="CHANGES">ChangeLog</a></li>
      <li><a href="#synopsis">Synopsis</a></li>
      <li><a href="#examples">Examples</a></li>
      <li><a href="#description">Description</a></li>
      <li><a href="#interface">Interface</a>
        <ul>
          <li>options
            <ul>
              <li><a href="#iterations">iterations</a></li>
              <li><a href="#nATime">nATime</a></li>
              <li><a href="#spikes">spikes</a></li>
              <li><a href="#cooldown">cooldown</a></li>
              <li><a href="#runCaps">runCaps</a></li>
              <li><a href="#responders-option">responders</a></li>
              <li><a href="#atInit">atInit</a></li>
              <li><a href="#atStart">atStart</a></li>
              <li><a href="#beforeTest">beforeTest</a></li>
              <li><a href="#afterTest">afterTest</a></li>
              <li><a href="#atFinish">atFinish</a></li>
              <li><a href="#atEnd">atEnd</a></li>
            </ul>
          </li>
        </ul>
      </li>
      <li><a href="#responders">Responders</a>
        <ul>
          <li>events
            <ul>
              <li><a href="#onInit">onInit</a></li>
              <li><a href="#onStart">onStart</a></li>
              <li><a href="#onIterate">onIterate</a></li>
              <li><a href="#onPause">onPause</a></li>
              <li><a href="#onResume">onResume</a></li>
              <li><a href="#onFinish">onFinish</a></li>
              <li><a href="#onComplete">onComplete</a></li>
            </ul>
          </li>
          <li><a href="#responders-suites">suites</a>
            <ul>
              <li><a href="benchmark_perlish.html">Perlish</a></li>
              <li><a href="benchmark_htmlish.html">HTMLish</a></li>
              <li><a href="benchmark_firebug.html">Firebug</a></li>
              <li><a href="benchmark_jsref.html">JSRef</a></li>
            </ul>
          </li>
        </ul>
      </li>
      <li>Addons
        <ul>
          <li><a href="benchmarker.html">Benchmarker</a></li>
        </ul>
      </li>
      <li><a href="#hacking">Hacking</a></li>
      <li><a href="#dependencies">Dependencies</a></li>
      <li><a href="#incompatibilities">Incompatibilities</a></li>
      <li><a href="#bugs">Bugs</a></li>
      <li><a href="#todo">To Do</a></li>
      <li><a href="#see-also">See Also</a></li>
      <li><a href="#credits">Credits</a></li>
      <li><a href="#authors">Authors</a></li>
      <li><a href="#license">License</a></li>
      <li><a href="#disclaimer">Disclaimer</a></li>
    </ul>

    <div class="section">
      <h2><a name="version">Version</a></h2>
      <p id="version-revision"><a href="benchmark.js">use the source, young padawan!</a></p>
    </div>

    <div class="section">
      <h2><a name="synopsis">Synopsis</a></h2>
<pre><code class="whjs">// "Basic" usage
new Benchmark(
  { // functions to be benchmarked
    foo: function(){ return 1+1 },
    bar: function(){ return 3-1 }
  }
);

// "Advanced" usage
new Benchmark(
  { // functions to be benchmarked
    upper: function(){ return this.TEST.toUpperCase() },
    LOWER: function(){ return this.TEST.toLowerCase() }
  },
  { // options
    iterations:  -2, // run each function for at least 2 seconds
    nATime: {
      upper: 1000, // run "upper" in chunks of 1000
      LOWER: 0     // automatically determine chunk value for "LOWER"
    },
    cooldown:    1000, // 1 second delay before resuming testing
    runCaps:     4000, // maximum 4 seconds for a continuous run
    responders:  'Perlish', // short-name of the 'responders' suite
    beforeStart: function() {
      // populate 'TEST' with the tested function's name
      this.TEST = this.current
    },
  }
);
</code></pre>
    </div>

    <div class="section">
      <h2><a name="examples">Examples</a></h2>
      <dl>
        <dt><a href="benchmark_t_split.html">String#split</a></dt>
        <dd>very basic example, yet quite useful as template for creating new benchmarks</dd>

        <dt><a href="benchmark_t_setStyle.html">Element#setStyle</a></dt>
        <dd>good for checking out how to deal with benchmarked functions' parasitic
          existence (and for using Benchmark handlers)</dd>

        <dt><a href="benchmark_t_escapeHTML.html">String#escapeHTML</a></dt>
        <dd>demonstration on how parasitic Benchmark really is (see how "TEST" is applied?)</dd>
      </dl>
      <p>
        Need more eye candy?
        See <a href="benchmarker.html#examples"><kbd>Benchmarker</kbd> examples</a>.
      </p>
    </div>

    <div class="section">
      <h2><a name="description">Description</a></h2>
      <p>
        This module started as JavaScript port of <a href="http://www.perl.org/">Perl</a>'s
        <a href="http://search.cpan.org/search?query=benchmark&amp;mode=module">Benchmark.pm</a>.
        Its <a href="#responders-perlish">default output</a> tries to be similar
        to its Perl cousin, but its internals evolved in a somehow different animal,
        more adapted for living in a web browser environment.
      </p>
    </div>

    <div class="section">
      <h2><a name="interface">Interface</a></h2>
      <pre><code class="whjs">  new Benchmark(functions, options);</code></pre>
      <p>
        Upon instantiating a <kbd>Benchmark</kbd>, it will automatically
        start benchmarking each provided <var>function</var>,
        triggering events along the way.
      </p>
      <p>
        Reusing <kbd>Benchmark</kbd> objects is possible, using
        the <kbd>run</kbd> method like in the following example:
      </p>
<pre><code class="whjs">  // instantiate *and* run benchmark
  var bm = new Benchmark({
    foo: function(){...},
    bar: function(){...}
  });
  // re-run benchmark for all methods ("foo" and "bar")
  bm.run();
  // re-run benchmark for method "foo" only
  bm.run('foo');
</code></pre>
      <p>
        This object operates in <em>liberal mode</em>, meaning that
        <strong>ALL</strong> options passed to the constructor will parasite
        it, no questions asked.  Even more, all handlers (including "responders")
        are executed in current <kbd>Benchmark</kbd> object's context,
        so using <kbd>this</kbd> in such a handler is appropriate.
      </p>
      <p>
        The functions to be benchmarked are to be provided as first argument.
        For example:
      </p>
<pre><code class="whjs">  new Benchmark({
    name_1: function() { /* function 1 code */},
    name_2: function() { /* function 2 code */}
  });
</code></pre>
      <p>
        No option is compulsory, sensible defaults are already in place.
        The currently used options are:
      </p>
      <dl>
        <dt>
          <a name="iterations">iterations</a>
          <kbd>{Number}</kbd>
          <samp>[<code class="whjs">-0.2</code>]</samp>
        </dt>
        <dd><em>if positive:</em> The number of iterations to run each method</dd>
        <dd><em>if negative:</em> The minimum number of seconds to run each method</dd>
        <dd><em>if null:</em> Use default (which is <kbd>-0.1</kbd>)</dd>

        <dt>
          <a name="nATime">nATime</a>
          <kbd>{Integer | Object}</kbd>
          <samp>[<code class="whjs">0</code>]</samp>
        </dt>
        <dd>
          The number of times a function is executed in a row (<em>tight-loop</em>).
          A better name could be “chunkSize” ;-)
        </dd>
        <dd>
          If <var>0</var> (default + <em>recommended</em>), Benchmark will to
          its best trying to automatically determine the best value for each
          to-be-tested function.
          Leaving it to <var>0</var> will make
          <a href="#spikes" title="error control">spikes control</a>
          behave better.
        </dd>
        <dd>
          If <var>Object</var>, Benchmark will consider it being a "Hash"
          containing particular <var>nATime</var> values for each named function.
        </dd>

        <dt>
          <a name="spikes">spikes</a>
          <kbd>{Number}</kbd>
          <samp>[<code class="whjs">5</code>]</samp>
        </dt>
        <dd>
          The maximum threshold between "worst" and "best", deciding if
          current chunk's results are to be ignored:
          <pre><code class="whjs">if (worst &gt; spikes * best) ignore()</code></pre>
          <p>
            A value less-or-equal than <var>1</var> would <em>disable</em> error control.
          </p>
          <p>
            Please notice that using a low enough value will make benchmark
            run for a possibly <em>very</em> long time until it will get a
            chance to obtain only “good” results
            (lowering <a href="#nATime">nATime</a> could help).
          </p>
        </dd>

        <dt>
          <a name="cooldown">cooldown</a>
          <kbd>{Integer}</kbd>
          <samp>[<code class="whjs">200</code>]</samp>
        </dt>
        <dd>The number of milliseconds of pause before resuming testing.</dd>

        <dt>
          <a name="runCaps">runCaps</a>
          <kbd>{Integer}</kbd>
          <samp>[<code class="whjs">3000</code>]</samp>
        </dt>
        <dd>
          The maximum number of milliseconds to run a test sequence before
          triggering a delay (used to work around current browsers script running caps,
          e.g. 
          <a href="http://www.mozilla.com/">Gecko</a>'s
          <a href="http://kb.mozillazine.org/Dom.max_script_run_time">dom.max_script_run_time</a>
          or
          <a href="http://www.microsoft.com/ie/">Internet Explorer</a>'s
          <a href="http://support.microsoft.com/?kbid=175500">script time-out</a>).
        </dd>

        <dt>
          <a name="responders-option">responders</a>
          <kbd>{String}</kbd>
          <samp>[<code class="whjs">'Perlish'</code>]</samp>
        </dt>
        <dd>The short-name of the <a href="#responders">Benchmark.Responders</a> "class".</dd>

        <dt>
          <a name="atInit">atInit</a>
          <kbd>{Function}</kbd>
          <samp>[<code class="whjs">function(){}</code>]</samp>
        </dt>
        <dd>
          This function will be called after Benchmark object initialization.
        </dd>

        <dt>
          <a name="atStart">atStart</a>
          <kbd>{Function}</kbd>
          <samp>[<code class="whjs">function(){}</code>]</samp>
        </dt>
        <dd>
          This function will be called before starting to benchmark a function.
        </dd>

        <dt>
          <a name="beforeTest">beforeTest</a>
          <kbd>{Function}</kbd>
          <samp>[<code class="whjs">function(){}</code>]</samp>
        </dt>
        <dd>
          This function will be called before each test iteration.
        </dd>

        <dt>
          <a name="afterTest">afterTest</a>
          <kbd>{Function}</kbd>
          <samp>[<code class="whjs">function(){}</code>]</samp>
        </dt>
        <dd>
          This function will be called after each test iteration.
        </dd>

        <dt>
          <a name="atFinish">atFinish</a>
          <kbd>{Function}</kbd>
          <samp>[<code class="whjs">function(){}</code>]</samp>
        </dt>
        <dd>
          This function will be called after finishing benchmarking a function.
        </dd>

        <dt>
          <a name="atEnd">atEnd</a>
          <kbd>{Function}</kbd>
          <samp>[<code class="whjs">function(){}</code>]</samp>
        </dt>
        <dd>
          This function will be called after all benchmarking is complete.
        </dd>
      </dl>
    </div>

    <div class="section">
      <h2><a name="responders">Benchmark.Responders</a></h2>
      <p>
        After each step, <var>Benchmark</var> tries to dispatch
        an event handler. These events handlers are:
      </p>
      <dl>
        <dt><a name="onInit"><kbd>onInit</kbd></a></dt>
        <dd>called after object's initialization;</dd>
        <dt><a name="onStart"><kbd>onStart</kbd></a></dt>
        <dd>called before starting to benchmark a function;</dd>
        <dt><a name="onIterate"><kbd>onIterate</kbd></a></dt>
        <dd>called after finishing a benchmark iteration;</dd>
        <dt><a name="onPause"><kbd>onPause</kbd></a></dt>
        <dd>called when interrupting the benchmarking process;</dd>
        <dt><a name="onResume"><kbd>onResume</kbd></a></dt>
        <dd>called when resuming the benchmarking process;</dd>
        <dt><a name="onFinish"><kbd>onFinish</kbd></a></dt>
        <dd>called after finishing benchmarking a function;</dd>
        <dt><a name="onComplete"><kbd>onComplete</kbd></a></dt>
        <dd>called after benchmarking for all functions is complete.</dd>
      </dl>
      <p>
        Each such handler is called in context of the current <kbd>Benchmark</kbd> object,
        possibly receiving a numeric argument describing the current position
        inside <a href="#hacking">the data structure</a>.
      </p>
      <p>
        Each responders suite should reside in a
        <samp>Benchmark.Responders.&lt;SuiteName&gt;</samp> object,
        all its methods being applied to the <kbd>Benchmark</kbd> object upon
        initialization.
      </p>

      <h3><a name="responders-suites">Ready-made Responders Suites</a></h3>
      <ul>
        <li><a href="benchmark_perlish.html">Perlish</a> - similar to Perl's Benchmark.pm</li>
        <li><a href="benchmark_htmlish.html">HTMLish</a> - fancy HTML#TABLE</li>
        <li><a href="benchmark_firebug.html">Firebug</a> - log results to <a href="http://getfirebug.com/">Firebug</a> console</li>
        <li><a href="benchmark_jsref.html">JSRef</a> - to be used in <a href="http://developer.mozilla.org/en/docs/Introduction_to_the_JavaScript_shell">the JavaScript Shell</a></li>
      </ul>
    </div>

    <div class="section">
      <h2><a name="hacking">Hacking</a></h2>
      <p>May I just say: <q>Use the source, Luke</q>? ;-)</p>
      <p>OK, here are a few hints:</p>
      <ul>
        <li><kbd>this.data</kbd> <kbd>{Object}</kbd>
          holds all benchmarking data, one item for every Function to be benchmarked;
<pre><code class="whjs">this.data = {
  method1: {
    name: 'method1',
    code: function() { /* method code */ },
    status: 0, // 0 - pending, 1 - running, 2 - done, 3 - failed
    nATime: 0,
    duration:   0, // cumulative counters (for successful tests)
    iterations: 0, // ! stay away of overflows ;-)
    lastRunIterations: 0, // "per run" counters,
    lastRunDuration:   0, // ! they are reset upon each "run"
    best:  Infinity, // ----------
    worst: 0,        // linear stats, cumulative
    avg:   0,        //
    rate:  0,        //
    comparison: {}   // ----------
    ignoredIterations:        0, // error counters
    lastRunIgnoredIterations: 0  //
  },
  // method2, ...
}</code></pre>
        </li>
        <li>
          all testing operations are executed in "asynchronous" mode
          (OK, it's just <em>simulated</em> using <kbd>setTimeout</kbd>);
        </li>
      </ul>
    </div>

    <div class="section">
      <h2><a name="dependencies">Dependencies</a></h2>
      <p>None.</p>
    </div>

    <div class="section">
      <h2><a name="incompatibilities">Incompatibilities</a></h2>
      <p>None reported.</p>
    </div>

    <div class="section">
      <h2><a name="bugs">Bugs and Limitations</a></h2>
      <p>No bugs have been reported.</p>
      <p>
        Obviously, it won't be able to benchmark functions that take
        more than browser's <a href="#runCaps">script running caps</a>
        for <a href="#nATime">nATime</a> function executions.
      </p>
      <p>
        Note that erratic results <strong>may</strong> occur, given
        the nondeterministic nature of the underlying testbed
        (a <var>browser</var>, a <var>computer</var>, etc).
        I'm still researching, some
        <a href="http://en.wikipedia.org/wiki/Error_control">error control</a>
        system would be a very useful addition to this library.
      </p>
    </div>

    <div class="section">
      <h2><a name="todo">To Do</a></h2>
      <ul>
        <li>enhance error control; how?</li>
      </ul>
    </div>

    <div class="section">
      <h2><a name="see-also">See Also</a></h2>
      <ul>
        <li><a href="benchmarker.html">Benchmarker</a></li>
      </ul>

      <p>
        Obviously, you <a href="http://www.google.com/search?q=javascript%20benchmark">may find</a>
        many javascript benchmarking tools around the web.
        Yet, I could not find anyone implementing it <a href="benchmark_perlish.html">like in Perl</a>.
      </p>
      <ul>
        <li>
          <a href="http://www.jorendorff.com/articles/javascript/speed-test.html">JavaScript speed test</a>
          — another approach on testing JS code speed.
          Check it out, it has lots of ready-made tests.
        </li>
        <li>
          <a href="http://www.p01.org/releases/DHTML_contests/files/20lines_JavaScript_benchmark/">JavaScript benchmark* 20 lines 'web developper tool'</a>
          — quick and dirty <code class="whjs">javaScriptBenchmark(for(var i=65536,j=0;i--;)j+=i;)</code>
        </li>
        <li>
          <a href="http://www.quirksmode.org/elsewhere/archives/tests/benchmarks/index.html">Elsewhere on the 'Net - Benchmarks</a>
          — Quirksmode.org: javascript benchmarks links
        </li>
        <li>
          some (more or less) <a href="http://trac.webkit.org/projects/webkit/wiki/JavaScript%20and%20DOM%20Benchmarks">random pointers</a>
          from <a href="http://www.webkit.org/">webkit.org</a>. could come handy though ;-)
        </li>
        <li> <a href="http://www.google.com/search?q=javascript%20benchmark">(google it)</a> </li>
      </ul>
    </div>

    <div class="section">
      <h2><a name="credits">Credits</a></h2>
      <ul>
        <li>Jarkko Hietaniemi &amp; Tim Bunce, authors of
          <a href="http://search.cpan.org/search?query=benchmark&amp;mode=module"><var>Benchmark.pm</var></a>
        </li>
        <li><a href="benchmarker.html#credits">JavaScript inspirational sources</a></li>
      </ul>
    </div>

    <div class="section">
      <h2><a name="authors">Authors</a></h2>
      <p>
        <a href="http://www.altblue.com/">Marius Feraru</a>,
        &lt;<a href="mailto:altblue@n0i.net">altblue@n0i.net</a>&gt;.
      </p>
    </div>

    <div class="section">
      <h2><a name="license">License and Copyright</a></h2>
      <p>
        &copy; 2006-2007 Marius Feraru &lt;altblue@n0i.net&gt;.
        All rights reserved.
      </p>
      <p>
        This module is free software; you can redistribute it
        and/or modify it under the same terms as Perl itself.
      </p>
    </div>

    <div class="section">
      <h2><a name="disclaimer">Disclaimer of Warranty</a></h2>
      <p>
        Because this software is licensed free of charge, there is no warranty
        for the software, to the extent permitted by applicable law. Except when
        otherwise stated in writing the copyright holders and/or other parties
        provide the software "as is" without warranty of any kind, either
        expressed or implied, including, but not limited to, the implied
        warranties of merchantability and fitness for a particular purpose.
        The entire risk as to the quality and performance of the software is
        with you. should the software prove defective, you assume the cost
        of all necessary servicing, repair, or correction.
      </p>
      <p>
        In no event unless required by applicable law or agreed to in writing
        will any copyright holder, or any other party who may modify and/or
        redistribute the software as permitted by the above license, be liable
        to you for damages, including any general, special, incidental,
        or consequential damages arising out of the use or inability to use
        the software (including but not limited to loss of data or data being
        rendered inaccurate or losses sustained by you or third parties or a
        failure of the software to operate with any other software), even if
        such holder or other party has been advised of the possibility of such
        damages.
      </p>
    </div>

    <script type="text/javascript">
      var hl = new Highlighter(false); hl.init();
      new Tree($('toc'));
      document.getElementById('version-revision').innerHTML = Benchmark.toString();
    </script>
  </body>
</html>
